package com.ly.web.controller.king;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.gson.Gson;
import com.kingdee.bos.webapi.entity.IdentifyInfo;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.erp.KingConstUtil;
import com.ly.heart.domain.KingBankAccountEntity;
import com.ly.heart.domain.KingOrgEntity;
import com.ly.heart.domain.king.base.BankAccountBo;
import com.ly.heart.domain.king.base.BaseModelBo;
import com.ly.heart.domain.request.KingBaseRequest;
import com.ly.heart.domain.response.KingBaseResponse;
import com.ly.heart.domain.response.KingBaseResponseError;
import com.ly.heart.domain.response.KingBaseResponseSuccessEntity;
import com.ly.heart.service.IKingBankAccountService;
import com.ly.heart.service.IKingOrgService;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.heart.util.KingCommonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Api ( value = "BankAccountRemote", tags = "推基础数据-银行账号" )
@RestController
@RequestMapping ( "/heart/BankAccountRemote" )
@Slf4j
public class BankAccountRemote {

    @Resource
    private IKingBankAccountService iKingBankAccountService;
    @Resource
    private IKingOrgService iKingOrgService;

    @ApiOperation ( "同步拉取金蝶银行账号" )
    @RequestMapping ( "pull" )
    public AjaxResult queryList () {
        KingOrgEntity orgEntity = iKingOrgService.getOne ( new LambdaQueryWrapper<KingOrgEntity> ().eq ( KingOrgEntity :: getOrgId, CurrentUserUtil.getCompanyId () ).eq ( KingOrgEntity :: getIsDisabled, false ) );
        if ( orgEntity == null ) {
            throw new CustomException ( "请先至系统管理中配置金蝶账套！" );
        }
        IdentifyInfo identifyInfo = KingCommonUtil.getIdentifyInfo ( orgEntity );
        K3CloudApi client = new K3CloudApi ( identifyInfo );
        //请求参数，要求为json字符串
        String jsonData = "{\"FormId\":\"" + KingConstUtil.CN_BANKACNT + "\",\"FieldKeys\":\"FNumber,FName,FACCOUNTTYPE,FBANKID,FIsFundUp,FUpType,FUpAmount,FBaseAmount,FMinUpAmount,FInOrOut,FIsSupBank,FISDEFAULTBANK,FIsAutoBlend,FIsSupAutoDER,FIsSupAutoDERT,FIsSupDZHD\",\"FilterString\":[],\"OrderString\":\"\",\"TopRowCount\":0,\"StartRow\":0,\"Limit\":2000,\"SubSystemId\":\"\"}";
        try {
            //调用接口
            List<List<Object>> lists = client.executeBillQuery ( jsonData );
            for ( int i = 0; i < lists.size (); i++ ) {
                List<Object> objects = lists.get ( i );
                //根据code查询是否已存在该结算方式
                String bizCode = ( String ) objects.get ( 0 );
                KingBankAccountEntity bankEntity = iKingBankAccountService.getBaseMapper ().selectOne ( new QueryWrapper<KingBankAccountEntity> ().eq ( "bank_code", bizCode ) );
                if ( bankEntity == null ) {
                    bankEntity = new KingBankAccountEntity ();
                    bankEntity.setDeptId ( CurrentUserUtil.getCompanyId () );
                    bankEntity.setAccount ( String.valueOf ( objects.get ( 0 ) ) );
                    bankEntity.setTitle ( String.valueOf ( objects.get ( 1 ) ) );
                    bankEntity.setAccountType ( String.valueOf ( objects.get ( 2 ) ) );
                    bankEntity.setBankCode ( String.valueOf ( objects.get ( 4 ) ) );
                    Boolean fundUp = ( Boolean ) objects.get ( 4 );
                    bankEntity.setFisFundUp ( fundUp == true ? 1 : 2 );//资金上划
                    bankEntity.setUpType ( String.valueOf ( objects.get ( 5 ) ) );
                    bankEntity.setUpAmount ( String.valueOf ( objects.get ( 6 ) ) );//
                    bankEntity.setBaseAmount ( String.valueOf ( objects.get ( 7 ) ) );//
                    bankEntity.setMinUpAmount ( String.valueOf ( objects.get ( 8 ) ) );
                    bankEntity.setInOrOut ( String.valueOf ( objects.get ( 9 ) ) );//
                    bankEntity.setIsSuperBank ( ( Boolean ) objects.get ( 10 ) == true ? 1 : 2 );//
                    bankEntity.setIsDefaultBank ( ( Boolean ) objects.get ( 11 ) == true ? 1 : 2 );//是否默认账户
                    bankEntity.setIsAutoBlend ( ( Boolean ) objects.get ( 12 ) == true ? 1 : 2 );//
                    bankEntity.setIsSuperAutoDer ( ( Boolean ) objects.get ( 13 ) == true ? 1 : 2 );//
                    bankEntity.setIsSuperAutoDert ( ( Boolean ) objects.get ( 14 ) == true ? 1 : 2 );//
                    bankEntity.setIsSuperDzhd ( ( Boolean ) objects.get ( 15 ) == true ? 1 : 2 );//
                    bankEntity.setIsSend ( KingConstUtil.KING_DATA_IS_SEND_YES );// 表示和金蝶已同步
                    iKingBankAccountService.insertKingBankEntity ( bankEntity );
                }
            }
        } catch ( Exception e ) {
            throw new RuntimeException ( "同步银行账号失败" );
        }
        return AjaxResult.success ( "同步银行账号成功" );
    }


    /**
     * 同步所有结算方式到金蝶
     *
     * @return
     */
    @ApiOperation ( "同步发送银行账号到金蝶" )
    @RequestMapping ( "push" )
    public AjaxResult push () throws Exception {
        KingOrgEntity orgEntity = iKingOrgService.getOne ( new LambdaQueryWrapper<KingOrgEntity> ().eq ( KingOrgEntity :: getOrgId, CurrentUserUtil.getCompanyId () ).eq ( KingOrgEntity :: getIsDisabled, false ) );
        if ( orgEntity == null ) {
            throw new CustomException ( "请先至系统管理中配置金蝶账套！" );
        }
        IdentifyInfo identifyInfo = KingCommonUtil.getIdentifyInfo ( orgEntity );
        K3CloudApi client = new K3CloudApi ( identifyInfo );
        List<KingBankAccountEntity> list = iKingBankAccountService.list ( new QueryWrapper<KingBankAccountEntity> ().eq ( "dept_id", CurrentUserUtil.getCompanyId () ).eq ( "is_send", KingConstUtil.KING_DATA_IS_SEND_NO ) );
        if ( CollectionUtils.isEmpty ( list ) ) {
            return AjaxResult.error ( "暂无新数据可推！" );
        }
        batchSave ( list, client );
        submit ( list, client );
        audit ( list, client );
        return AjaxResult.success ( "推送银行账号成功。" );
    }


    /**
     * 推送结算方式
     *
     * @param list
     * @param client
     * @throws Exception
     */
    private void batchSave ( List<KingBankAccountEntity> list, K3CloudApi client ) throws Exception {
        KingBaseRequest request = new KingBaseRequest ();
        List<BaseModelBo> bos = new ArrayList<> ();
        list.forEach ( bankEntity -> {
            BankAccountBo bo = new BankAccountBo ();
            bo.setFNumber ( bankEntity.getAccount () );//账号
            bo.setFName ( bankEntity.getTitle () );
            bo.setFACCOUNTTYPE ( bankEntity.getAccountType () );//账号类型
            bo.setFIsFundUp ( String.valueOf ( bankEntity.getFisFundUp () ) );
            bo.setFUpType ( bankEntity.getUpType () );
            bo.setFUpAmount ( bankEntity.getUpAmount () );
            bo.setFBaseAmount ( bankEntity.getBaseAmount () );
            bo.setFMinUpAmount ( bankEntity.getMinUpAmount () );
            bo.setFInOrOut ( bankEntity.getInOrOut () );
            bo.setFIsSupBank ( bankEntity.getIsSuperBank () == 1 ? true : false );
            bo.setFISDEFAULTBANK ( bankEntity.getIsDefaultBank () == 1 ? true : false );
            bo.setFIsAutoBlend ( bankEntity.getIsAutoBlend () == 1 ? true : false );
            bo.setFIsSupAutoDER ( bankEntity.getIsSuperAutoDer () == 1 ? true : false );
            bo.setFIsSupAutoDERT ( bankEntity.getIsSuperAutoDert () == 1 ? true : false );
            bo.setFIsSupDZHD ( bankEntity.getIsSuperDzhd () == 1 ? true : false );
            bos.add ( bo );
        } );
        request.setModel ( bos );
        String s = JSONObject.toJSONString ( request );
        log.info ( "bos-》{}", bos );
        log.info ( "s->{}", s );
        String resultJson = client.batchSave ( KingConstUtil.CN_BANKACNT, s );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () == true ) {
            //添加成功，进行提交
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "银行账户-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.info ( "{} 推送成功", sb );
            //修改为已推送状态
            list.forEach ( bankEntity -> {
                iKingBankAccountService.update ( new UpdateWrapper<KingBankAccountEntity> ().
                        set ( "is_send", KingConstUtil.KING_DATA_IS_SEND_YES ).
                        set ( "update_time", DateUtils.getNowDate () ).
                        eq ( "account", bankEntity.getAccount () ) );
            } );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "银行账户-推送失败：【" + sb + "】" );
        }
    }


    /**
     * 提交结算方式
     *
     * @param list
     * @param client
     */
    private void submit ( List<KingBankAccountEntity> list, K3CloudApi client ) throws Exception {
        BankAccountBo bo = new BankAccountBo ();
        List<String> strings = new ArrayList<> ();
        list.forEach ( bankEntity -> {
            strings.add ( bankEntity.getAccount () );
        } );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.submit ( KingConstUtil.CN_BANKACNT, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () == true ) {
            //提交成功
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "银行账户-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.error ( "{} 提交成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "银行账户提交失败：【" + sb + "】" );
        }
    }

    /**
     * 结算方式审核
     *
     * @param list
     * @param client
     */
    private void audit ( List<KingBankAccountEntity> list, K3CloudApi client ) throws Exception {
        BankAccountBo bo = new BankAccountBo ();
        List<String> strings = new ArrayList<> ();
        list.forEach ( bankEntity -> {
            strings.add ( bankEntity.getAccount () );
        } );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.audit ( KingConstUtil.CN_BANKACNT, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () == true ) {
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "银行账户-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.info ( "{} 审核成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "银行账户审核失败：【" + sb + "】" );
        }
    }

}
